package thoven.achievement.net.ideapluginachievement.service

import com.intellij.openapi.components.Service
import com.intellij.openapi.project.Project
import thoven.achievement.net.ideapluginachievement.model.AchievementType
import java.io.Serializable
import java.time.DayOfWeek
import java.time.LocalDate

/**
 * 智能洞察分析服务
 * 基于用户的编码数据生成个性化建议和洞察
 */
@Service(Service.Level.PROJECT)
class InsightService(private val project: Project) {
    
    private val codeStatsService = CodeStatsService.getInstance(project)
    
    /**
     * 生成今日洞察
     */
    fun generateTodayInsights(): List<Insight> {
        val insights = mutableListOf<Insight>()
        
        // 1. 分析今日编码量
        insights.addAll(analyzeTodayCodingVolume())
        
        // 2. 分析代码删除占比
        insights.addAll(analyzeCodeDeletionRatio())
        
        // 3. 分析连续编码天数
        insights.addAll(analyzeConsecutiveDays())
        
        // 4. 分析即将解锁的成就
        insights.addAll(analyzeUpcomingAchievements())
        
        return insights
    }
    
    /**
     * 生成本周洞察
     */
    fun generateWeeklyInsights(): List<Insight> {
        val insights = mutableListOf<Insight>()
        
        // 1. 分析本周活跃度
        insights.addAll(analyzeWeeklyActivity())
        
        // 2. 分析编码时间偏好
        insights.addAll(analyzeCodingTimePreference())
        
        // 3. 分析语言使用情况
        insights.addAll(analyzeLanguageUsage())
        
        return insights
    }
    
    /**
     * 生成本月洞察
     */
    fun generateMonthlyInsights(): List<Insight> {
        val insights = mutableListOf<Insight>()
        
        // 1. 分析本月编码习惯
        insights.addAll(analyzeMonthlyHabits())
        
        // 2. 分析成就解锁进度
        insights.addAll(analyzeAchievementProgress())
        
        // 3. 生成下月建议
        insights.addAll(generateNextMonthSuggestions())
        
        return insights
    }
    
    /**
     * 分析今日编码量
     */
    private fun analyzeTodayCodingVolume(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val stats = codeStatsService.getAggregatedStats()
        
        when {
            stats.todayAdded == 0 -> {
                insights.add(Insight(
                    type = InsightType.MOTIVATION,
                    title = "今天还没开始编码",
                    description = "写下第一行代码，开启今天的编程之旅吧！",
                    icon = "💡"
                ))
            }
            stats.todayAdded < 50 -> {
                insights.add(Insight(
                    type = InsightType.ENCOURAGEMENT,
                    title = "小步慢跑",
                    description = "今天写了${stats.todayAdded}行代码，保持节奏，循序渐进！",
                    icon = "🏃"
                ))
            }
            stats.todayAdded in 100..299 -> {
                insights.add(Insight(
                    type = InsightType.ACHIEVEMENT_UNLOCKED,
                    title = "稳定输出",
                    description = "今天已经写了${stats.todayAdded}行代码，保持这个状态！",
                    icon = "✨"
                ))
            }
            stats.todayAdded >= 500 -> {
                insights.add(Insight(
                    type = InsightType.CELEBRATION,
                    title = "爆肝模式",
                    description = "今天已经写了${stats.todayAdded}行代码！注意休息，劳逸结合哦",
                    icon = "🔥"
                ))
            }
        }
        
        return insights
    }
    
    /**
     * 分析代码删除占比
     */
    private fun analyzeCodeDeletionRatio(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val stats = codeStatsService.getAggregatedStats()
        
        if (stats.todayAdded > 0) {
            val deletionRatio = (stats.todayDeleted.toDouble() / stats.todayAdded * 100).toInt()
            
            when {
                deletionRatio >= 50 -> {
                    insights.add(Insight(
                        type = InsightType.REFACTORING,
                        title = "重构大师",
                        description = "本周删除代码占比${deletionRatio}%，重构意识很强！",
                        icon = "♻️"
                    ))
                }
                deletionRatio >= 30 -> {
                    insights.add(Insight(
                        type = InsightType.REFACTORING,
                        title = "代码优化中",
                        description = "删除了${deletionRatio}%的代码，正在优化代码质量",
                        icon = "🧹"
                    ))
                }
                deletionRatio >= 10 -> {
                    insights.add(Insight(
                        type = InsightType.INFO,
                        title = "适度重构",
                        description = "删除代码占比${deletionRatio}%，保持健康的代码迭代节奏",
                        icon = "📊"
                    ))
                }
            }
        }
        
        return insights
    }
    
    /**
     * 分析连续编码天数
     */
    private fun analyzeConsecutiveDays(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val consecutiveDays = codeStatsService.getConsecutiveDays()
        
        when {
            consecutiveDays >= 30 -> {
                insights.add(Insight(
                    type = InsightType.STREAK,
                    title = "坚持不懈",
                    description = "已连续编码${consecutiveDays}天！你的毅力令人钦佩",
                    icon = "🏆"
                ))
            }
            consecutiveDays >= 7 -> {
                insights.add(Insight(
                    type = InsightType.STREAK,
                    title = "一周坚持",
                    description = "已连续编码${consecutiveDays}天，继续保持这个好习惯！",
                    icon = "🔥"
                ))
            }
            consecutiveDays >= 3 -> {
                insights.add(Insight(
                    type = InsightType.STREAK,
                    title = "渐入佳境",
                    description = "已连续编码${consecutiveDays}天，再坚持几天就能解锁「一周坚持」成就！",
                    icon = "💪"
                ))
            }
        }
        
        return insights
    }
    
    /**
     * 分析即将解锁的成就
     */
    private fun analyzeUpcomingAchievements(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val closestAchievements = codeStatsService.getClosestAchievements(2)
        
        closestAchievements.filter { it.progressPercent >= 50 }.forEach { progress ->
            insights.add(Insight(
                type = InsightType.ACHIEVEMENT_PROGRESS,
                title = "距离「${progress.name}」还差${progress.remainingValue()}",
                description = "当前进度${progress.progressPercent}%，继续加油！",
                icon = "🎯"
            ))
        }
        
        return insights
    }
    
    /**
     * 分析本周活跃度
     */
    private fun analyzeWeeklyActivity(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val today = LocalDate.now()
        val startOfWeek = today.minusDays(today.dayOfWeek.value.toLong() - 1)
        val weekStats = codeStatsService.getStatsByDateRange(startOfWeek, today)
        val activeDays = weekStats.map { it.date }.distinct().size
        
        when {
            activeDays >= 5 -> {
                insights.add(Insight(
                    type = InsightType.ACTIVITY,
                    title = "本周超级活跃",
                    description = "本周已编码${activeDays}天，工作状态非常棒！",
                    icon = "⭐"
                ))
            }
            activeDays >= 3 -> {
                insights.add(Insight(
                    type = InsightType.ACTIVITY,
                    title = "本周稳定输出",
                    description = "本周已编码${activeDays}天，保持这个节奏！",
                    icon = "✨"
                ))
            }
            activeDays >= 1 -> {
                insights.add(Insight(
                    type = InsightType.MOTIVATION,
                    title = "本周可以更活跃",
                    description = "本周只编码了${activeDays}天，试着增加编码频率吧",
                    icon = "📅"
                ))
            }
        }
        
        return insights
    }
    
    /**
     * 分析编码时间偏好
     */
    private fun analyzeCodingTimePreference(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val today = LocalDate.now()
        val weekStart = today.minusDays(6)
        val weekStats = codeStatsService.getStatsByDateRange(weekStart, today)
        
        // 统计周末编码情况
        val weekendStats = weekStats.filter { 
            it.date.dayOfWeek == DayOfWeek.SATURDAY || it.date.dayOfWeek == DayOfWeek.SUNDAY 
        }
        val weekendLines = weekendStats.sumOf { it.addedLines }
        
        if (weekendLines > 200) {
            insights.add(Insight(
                type = InsightType.TIME_PATTERN,
                title = "周末战士",
                description = "过去7天在周末编写了${weekendLines}行代码，工作狂人属性已激活！",
                icon = "💼"
            ))
        }
        
        return insights
    }
    
    /**
     * 分析语言使用情况
     */
    private fun analyzeLanguageUsage(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val today = LocalDate.now()
        val weekStart = today.minusDays(6)
        val weekStats = codeStatsService.getStatsByDateRange(weekStart, today)
        val languages = weekStats.map { it.language }.distinct().filter { it != "Unknown" }
        
        when {
            languages.size >= 5 -> {
                insights.add(Insight(
                    type = InsightType.LANGUAGE_DIVERSITY,
                    title = "多语言大师",
                    description = "本周使用了${languages.size}种编程语言：${languages.take(5).joinToString(", ")}",
                    icon = "🌍"
                ))
            }
            languages.size >= 3 -> {
                insights.add(Insight(
                    type = InsightType.LANGUAGE_DIVERSITY,
                    title = "语言多样性",
                    description = "本周使用了${languages.size}种语言：${languages.joinToString(", ")}",
                    icon = "🗣️"
                ))
            }
            languages.size == 1 -> {
                insights.add(Insight(
                    type = InsightType.INFO,
                    title = "专注${languages.first()}",
                    description = "本周专注于${languages.first()}开发，术业有专攻！",
                    icon = "🎯"
                ))
            }
        }
        
        return insights
    }
    
    /**
     * 分析本月编码习惯
     */
    private fun analyzeMonthlyHabits(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val today = LocalDate.now()
        val monthStart = today.withDayOfMonth(1)
        val monthStats = codeStatsService.getStatsByDateRange(monthStart, today)
        
        val activeDays = monthStats.map { it.date }.distinct().size
        val totalAdded = monthStats.sumOf { it.addedLines }
        val avgPerDay = if (activeDays > 0) totalAdded / activeDays else 0
        
        insights.add(Insight(
            type = InsightType.MONTHLY_SUMMARY,
            title = "本月编码习惯",
            description = "本月活跃${activeDays}天，日均编写${avgPerDay}行代码",
            icon = "📊"
        ))
        
        return insights
    }
    
    /**
     * 分析成就解锁进度
     */
    private fun analyzeAchievementProgress(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val allProgress = codeStatsService.getAllAchievementProgress()
        val unlockedCount = allProgress.count { it.isUnlocked }
        val totalCount = allProgress.size
        val completionRate = (unlockedCount.toDouble() / totalCount * 100).toInt()
        
        insights.add(Insight(
            type = InsightType.ACHIEVEMENT_SUMMARY,
            title = "成就完成度${completionRate}%",
            description = "已解锁${unlockedCount}/${totalCount}个成就，继续努力收集徽章！",
            icon = "🏅"
        ))
        
        return insights
    }
    
    /**
     * 生成下月建议
     */
    private fun generateNextMonthSuggestions(): List<Insight> {
        val insights = mutableListOf<Insight>()
        val consecutiveDays = codeStatsService.getConsecutiveDays()
        
        when {
            consecutiveDays >= 20 && consecutiveDays < 30 -> {
                insights.add(Insight(
                    type = InsightType.SUGGESTION,
                    title = "下月目标建议",
                    description = "你已连续编码${consecutiveDays}天，下月可以挑战「月度坚持」成就！",
                    icon = "🎯"
                ))
            }
            consecutiveDays < 7 -> {
                insights.add(Insight(
                    type = InsightType.SUGGESTION,
                    title = "下月目标建议",
                    description = "试着保持每周至少编码5天，养成良好的编程习惯",
                    icon = "📅"
                ))
            }
        }
        
        return insights
    }
    
    companion object {
        fun getInstance(project: Project): InsightService {
            return project.getService(InsightService::class.java)
        }
    }
}

/**
 * 洞察类型
 */
enum class InsightType {
    MOTIVATION,              // 激励
    ENCOURAGEMENT,           // 鼓励
    ACHIEVEMENT_UNLOCKED,    // 成就解锁
    ACHIEVEMENT_PROGRESS,    // 成就进度
    ACHIEVEMENT_SUMMARY,     // 成就总结
    CELEBRATION,             // 庆祝
    REFACTORING,             // 重构
    STREAK,                  // 连续性
    ACTIVITY,                // 活跃度
    TIME_PATTERN,            // 时间模式
    LANGUAGE_DIVERSITY,      // 语言多样性
    MONTHLY_SUMMARY,         // 月度总结
    SUGGESTION,              // 建议
    INFO                     // 信息
}

/**
 * 洞察数据模型
 */
data class Insight(
    val type: InsightType,
    val title: String,
    val description: String,
    val icon: String
) : Serializable

